package cn.yqx.bankshop.gateway.filter;

import cn.yqx.bankshop.constants.HttpConstant;
import cn.yqx.bankshop.result.Result;
import cn.yqx.bankshop.result.ResultCode;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;

import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;
import java.net.InetSocketAddress;
import java.util.Objects;

@Slf4j
@Component
public class GeteWayFilterConfig implements GlobalFilter {

    private static final String[] WHITE_LIST = {"/oauth/token","/oauth/check_token","/oauth/logout","/my-logout","/api/v1/user-auth","/authentication/form","/code/sms","/authentication/mobile","/code/image"};
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String uriPath = request.getPath().toString();
        boolean action = false;
        String token = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        for (String url : WHITE_LIST) {
            if (antPathMatcher.match(url, uriPath)) {
                action = true;
                break ;
            }
        }
        if (action) {
            return chain.filter(exchange);
        }

        if (null == token || token.isEmpty()) {

            ServerHttpResponse response = exchange.getResponse();
            InetSocketAddress remoteAddress = request.getRemoteAddress();
            String clientIp = Objects.requireNonNull(remoteAddress).getAddress().getHostAddress();

            log.info("非法请求，客户端IP：" + clientIp + "URL：" + request.getPath());

            Result result = Result.failed(ResultCode.HTTP_ERROR_NO_TOKEN);
            DataBuffer buffer = response.bufferFactory().wrap(JSON.toJSONBytes(result));
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add(HttpConstant.CONTENT_TYPE, HttpConstant.APPLICATION_JSON);
            return response.writeWith(Mono.just(buffer));

        }

        //判断token是否有效,如果无效就直接pass
        ServerHttpRequest authorization = request.mutate().headers(httpHeaders -> {
            httpHeaders.add(HttpHeaders.AUTHORIZATION, token);
        }).build();

        ServerWebExchange serverWebExchange = exchange.mutate().request(authorization).build();
        return chain.filter(serverWebExchange);

    }
}
